/****************************************************************************
 *  _____       ______  _____
 * |_   _|     |  ____|/ ____|
 *   | |  _ __ | |__  | (___    Institute of Embedded Systems
 *   | | | '_ \|  __|  \___ \   Zürcher Hochschule für Angewandte
 *  _| |_| | | | |____ ____) |  Wissenschaften
 * |_____|_| |_|______|_____/   8401 Winterthur, Switzerland
 *
 ****************************************************************************
 *
 * @version $Rev: 153 $
 * @author  $Author: bacr $
 * @date    $Date: 2013-10-10 17:25:34 +0200 (jeu., 10 oct. 2013) $
 *
 ***************************************************************************/

#ifndef __PTP2_ANNOUNCE_PACKET_H__
#define __PTP2_ANNOUNCE_PACKET_H__

#include "hcpp/ptp2_types.h"

typedef struct ptp2_announce_header_t ptp2_announce_header_t;
typedef struct ptp2_announce_packet_t ptp2_announce_packet_t;

#define PTP2_ANNOUNCE_PACKET(obj) ((ptp2_announce_packet_t *) obj)

#define PTP2_ANNOUNCE_PACKET_LEN                                 30

#define PTP2_ANNOUNCE_PACKET_OFFSET_ORIGIN_TIMESTAMP             0
#define PTP2_ANNOUNCE_PACKET_OFFSET_CURRENT_UTC_OFFSET           10
#define PTP2_ANNOUNCE_PACKET_OFFSET_GM_PRIORITY1                 13
#define PTP2_ANNOUNCE_PACKET_OFFSET_GM_CLOCK_QUALITY             14
#define PTP2_ANNOUNCE_PACKET_OFFSET_GM_PRIORITY2                 18
#define PTP2_ANNOUNCE_PACKET_OFFSET_GM_IDENTITY                  19
#define PTP2_ANNOUNCE_PACKET_OFFSET_STEPS_REMOVED                27
#define PTP2_ANNOUNCE_PACKET_OFFSET_TIME_SOURCE                  29

/* network byte order */
#define PTP2_ANNOUNCE_HEADER                        \
    ptp2_timestamp_t        origin_timestamp;       \
    int16_t                 current_utc_offset;     \
    uint8_t                 gm_priority1;           \
    ptp2_clock_quality_t    gm_clock_quality;       \
    uint8_t                 gm_priority2;           \
    ptp2_clock_identity_t   gm_identity;            \
    uint16_t                steps_removed;          \
    uint8_t                 time_source;

/**
 * @struct ptp2_announce_header_t
 * @brief  PTPv2 announce header
 * @see    ptp2_announce_packet_t
 *
 */
struct ptp2_announce_header_t {
    PTP2_ANNOUNCE_HEADER
};

/**
 * @struct ptp2_announce_packet_t
 * @brief  PTPv2 announce packet
 * @see    ptp2_announce_packet_t
 *
 * @var    ptp2_announce_packet_t::ether
 * @brief  Ethernet header
 *
 * @var    ptp2_announce_packet_t::ip
 * @brief  IP header
 *
 * @var    ptp2_announce_packet_t::udp
 * @brief  UDP header
 *
 * @var    ptp2_announce_packet_t::ptp
 * @brief  PTPv2 header
 */
struct ptp2_announce_packet_t {
    object_t            obj;
    info_header_t       info;
    ethernet_header_t   ether;      /**< @brief Ethernet header */
    ip_header_t         ip;         /**< @brief IP header */
    udp_header_t        udp;        /**< @brief UDP header */
    ptp2_header_t       ptp;        /**< @brief PTP header */
    PTP2_ANNOUNCE_HEADER
};

uint32_t    ptp2_announce_packet_encode(ptp2_announce_packet_t *this, raw_packet_t *raw_packet, uint32_t ptp2_announce_offset);
void        ptp2_announce_packet_decode(ptp2_announce_packet_t *this, raw_packet_t *raw_packet, uint32_t ptp2_announce_offset);

#endif

